package com.ezandroid.library.image.ext.core.display;

import android.animation.Animator;
import android.animation.ObjectAnimator;
import android.graphics.Bitmap;
import android.view.View;
import android.view.animation.AccelerateInterpolator;
import android.widget.ImageView;

import com.nostra13.universalimageloader.core.assist.LoadedFrom;
import com.nostra13.universalimageloader.core.display.BitmapDisplayer;
import com.nostra13.universalimageloader.core.imageaware.ImageAware;

public class FadeOutBitmapDisplayer implements BitmapDisplayer {

    private final int durationMillis;

    private final boolean animateFromNetwork;
    private final boolean animateFromDisk;
    private final boolean animateFromMemory;

    private final float originAlpha;
    private final float targetAlpha;

    /**
     * @param durationMillis Duration of "fade-in" animation (in milliseconds)
     */
    public FadeOutBitmapDisplayer(int durationMillis) {
        this(durationMillis, true, true, true);
    }

    /**
     * @param durationMillis     Duration of "fade-in" animation (in milliseconds)
     * @param animateFromNetwork Whether animation should be played if image is loaded from
     *                           network
     * @param animateFromDisk    Whether animation should be played if image is loaded from
     *                           disk cache
     * @param animateFromMemory  Whether animation should be played if image is loaded from
     *                           memory cache
     */
    public FadeOutBitmapDisplayer(int durationMillis, boolean animateFromNetwork,
                                  boolean animateFromDisk, boolean animateFromMemory) {
        this(durationMillis, animateFromNetwork, animateFromDisk, animateFromMemory, 1.0f, 0.0f);
    }

    public FadeOutBitmapDisplayer(int durationMillis, boolean animateFromNetwork,
                                  boolean animateFromDisk, boolean animateFromMemory, float originAlpha, float targetAlpha) {
        this.durationMillis = durationMillis;
        this.animateFromNetwork = animateFromNetwork;
        this.animateFromDisk = animateFromDisk;
        this.animateFromMemory = animateFromMemory;
        this.originAlpha = originAlpha;
        this.targetAlpha = targetAlpha;
    }

    @Override
    public void display(Bitmap bitmap, ImageAware imageAware, LoadedFrom loadedFrom) {
        imageAware.setImageBitmap(bitmap);

        if ((animateFromNetwork && loadedFrom == LoadedFrom.NETWORK)
                || (animateFromDisk && loadedFrom == LoadedFrom.DISC_CACHE)
                || (animateFromMemory && loadedFrom == LoadedFrom.MEMORY_CACHE)) {
            animate(imageAware.getWrappedView(), durationMillis, originAlpha, targetAlpha);
        }
    }

    /**
     * Animates {@link ImageView} with "fade-out" effect
     *
     * @param imageView      {@link ImageView} which display image in
     * @param durationMillis The length of the animation in milliseconds
     */
    public static void animate(View imageView, int durationMillis, float originAlpha,
                               float targetAlpha) {
        if (imageView != null) {
            Animator alphaAnimator = ObjectAnimator.ofFloat(imageView, "alpha", originAlpha,
                    targetAlpha);
            alphaAnimator.setInterpolator(new AccelerateInterpolator());
            alphaAnimator.start();
        }
    }
}
